package com.traitswu.simple.demo.service;

import com.traitswu.simple.demo.store.FileDesc;
import com.traitswu.simple.demo.store.LocalStore;
import com.traitswu.simple.demo.store.Store;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;


@Service
public class FileUpdownServiceImpl implements FileUpdownService {


    private Store store = new LocalStore();

    @Value("${file.store.root}")
    private String storeRoot;

    @Value("${file.store.tmp}")
    private String tmpDir;


    @Override
    public FileDesc upload(InputStream inputStream, String path) throws IOException {
        File file = new File(storeRoot, path);
        FileDesc fileDesc = store.save(inputStream, file.getParent(), file.getName());
        String relativePath = Paths.get(this.storeRoot).relativize(Paths.get(fileDesc.getUrl())).toString();
        return new FileDesc(fileDesc.getName(), relativePath);
    }


    @Override
    public FileDesc uploadBeforeConfirm(InputStream inputStream, String path) throws IOException {
        File file = new File(tmpDir, path);
        FileDesc fileDesc = store.save(inputStream, file.getParent(), file.getName());
        String relativePath = Paths.get(this.tmpDir).relativize(Paths.get(fileDesc.getUrl())).toString();
        return new FileDesc(fileDesc.getName(), relativePath);
    }

    @Override
    public FileDesc uploadAfterConfirmed(FileDesc tmp) throws IOException {
        // Only file move
        File target = new File(this.tmpDir, tmp.getUrl());
        if (!target.exists()) {
            throw new FileNotFoundException("File not found:" + tmp.getUrl());
        }

        File dest = new File(storeRoot, tmp.getUrl());

        boolean isSucc = store.move(target.getPath(), dest.getPath());
        if (!isSucc) {
            throw new IllegalArgumentException("Move file failled.");
        }

        return new FileDesc(tmp.getName(), tmp.getUrl());
    }

    @Override
    public InputStream download(FileDesc fileDesc) throws IOException {
        FileDesc defaultResource = new FileDesc(fileDesc.getName(), fileDesc.getUrl());
        Path path = Paths.get(fileDesc.getUrl());
        if (!path.startsWith(Paths.get(this.storeRoot))) {
            defaultResource = new FileDesc(fileDesc.getName(), Paths.get(this.storeRoot, fileDesc.getUrl()).toString());
        }

        return this.store.read(defaultResource);
    }

    @Override
    public InputStream download(String url) throws IOException {
        return download(new FileDesc(new File(url).getName(), url));
    }
}
